import {
    db, UserModel,SettingModel, DomainModel, Handler, UserNotFoundError, param, PERM, PRIV, Types, paginate, query
} from 'hydrooj';

// 修复 `getListForRender` 函数，给前端传递更多内容
export const coll: Collection<Udoc> = db.collection('user');
export const collV: Collection<VUdoc> = db.collection('vuser');
export const collGroup: Collection<GDoc> = db.collection('user.group');
UserModel.getListForRender = async function (domainId: string, uids: number[], arg: string[] | boolean) {
        const fields = ['_id', 'uname', 'mail', 'avatar', 'school', 'studentId', 'realname_flag', 'realname_name'].concat(arg instanceof Array ? arg : []);
        const showDisplayName = arg instanceof Array ? fields.includes('displayName') : arg;
        const [udocs, vudocs, dudocs] = await Promise.all([
            UserModel.getMulti({ _id: { $in: uids } }, fields).toArray(),
            collV.find({ _id: { $in: uids } }).toArray(),
            DomainModel.getDomainUserMulti(domainId, uids).project({ uid: 1, ...(showDisplayName ? { displayName: 1 } : {}) }).toArray(),
        ]);
        const udict = {};
        for (const udoc of udocs) udict[udoc._id] = udoc;
        for (const udoc of vudocs) udict[udoc._id] = udoc;
        if (showDisplayName) for (const dudoc of dudocs) udict[dudoc.uid].displayName = dudoc.displayName;
        for (const uid of uids) udict[uid] ||= { ...UserModel.defaultUser };
        for (const key in udict) {
            udict[key].school ||= '';
            udict[key].studentId ||= '';
            udict[key].displayName ||= udict[key].uname;
            udict[key].avatar ||= `gravatar:${udict[key].mail}`;
        }
        return udict as BaseUserDict;
};

//实名设置
class RealnameSetHandler extends Handler {
    @query('uname', Types.string, true)
    @query('name', Types.string, true)
    async get(domainId: string, uname: string, name: string) {
        this.response.template = 'realname_set.html'; // 返回此页面
        this.response.body = {
            uname,name,
        };
    }
    @param('uidOrName', Types.UidOrName)
    @param('flag', Types.number,true)
    @param('name', Types.string,true)
    async post(domainId: string, uidOrName: string, flag: number, name: string) {
        // 检查输入
        flag = parseInt(flag);       
        let udoc = await UserModel.getByUname(domainId, uidOrName);
        if (!udoc)
            throw new UserNotFoundError(uidOrName);
        // 构建实名代码并更新
        //await UserModel.setById(udoc._id, { realname_flag: flag, realname_name: name });

        if ([0,1,2].includes(flag)) await UserModel.setById(udoc._id, { realname_flag: flag });
        if (name) await UserModel.setById(udoc._id, { realname_name: name.trim() });
 
        // 将用户重定向到创建完成的url
        this.response.redirect = this.url('realname_show');
    }
}

//展示实名用户
class RealnameShowHandler extends Handler {
    @query('page', Types.PositiveInt, true)
    @query('group', Types.string, true)
    async get(domainId: string, page = 1, group: string) {

        let filter = { realname_flag: { $exists: true, $ne: "" } };

	const groups = await UserModel.listGroup(domainId);
        if (group) {
            const groupInfo = groups.find(g => g.name === group);
            if (groupInfo) {
                filter._id = { $in: groupInfo.uids };
            }
        }

        const [dudocs, upcount, ucount] = await paginate(
            UserModel.getMulti(filter).sort({ realname_flag: -1, _id: -1 }),
            page,
            100,
        );
        const udict = await UserModel.getList(domainId, dudocs.map((x) => x._id));
        const udocs = dudocs.map((x) => udict[x._id]);
        this.response.template = 'realname_show.html'; // 返回此页面
        this.response.body = { udocs, upcount, ucount, page, group, groups, };
    }
}

//导入实名用户
class RealnameImportHandler extends Handler {
   async get() {
        this.response.template = 'realname_import.html'; // 返回此页面
    }
    @param('realnames', Types.Content)
    async post(domainId: string, _realnames: string) {
        const realnames = _realnames.split('\n');
        const udocs: { uidOrName: string, flag: number, name: string }[] = [];
        for (const i in realnames) {
            const u = realnames[i];
            if (!u.trim()) continue;
            let [uidOrName, flag, name] = u.split('\t').map((t) => t.trim());
            if (uidOrName && !flag && !name) {
                const data = u.split(',').map((t) => t.trim());
                [uidOrName, flag, name] = data;
            }

            if (!uidOrName) continue;
                flag = parseInt(flag);
                udocs.push({
                    uidOrName, flag, name,
                });
        }
        for (const udoc of udocs) {
            let user = await UserModel.getByUname(domainId, udoc.uidOrName);
            if (!user) continue;
            // 构建实名代码并更新
            // await UserModel.setById(user._id, { realname_flag: udoc.flag, realname_name: udoc.name });
            if(![0,1,2].includes(udoc.flag) && udoc.name=='')
            {
              await UserModel.setById(user._id, { realname_flag: '', realname_name: '' });
            }
            else
            {
              if([0,1,2].includes(udoc.flag)) await UserModel.setById(user._id, { realname_flag: udoc.flag });
              if(udoc.name) await UserModel.setById(user._id, { realname_name: udoc.name });
            }
          }
        this.response.redirect = this.url('realname_show');
    }
}

//修改密码
class ResetPwdHandler extends Handler {
    @query('uname', Types.string, true)
    async get(domainId: string, uname: string) {
        this.response.template = 'realname_resetpwd.html'; // 返回此页面
        this.response.body = {
            uname,
        };
    }
    @param('uidOrName', Types.UidOrName)
    @param('resetpwd', Types.Password)
    async post(domainId: string, uidOrName: string, resetpwd: string) {
        // 检查输入
        let udoc = await UserModel.getByUname(domainId, uidOrName);
        if (!udoc)
            throw new UserNotFoundError(uidOrName);
        // 构建实名代码并更新
        await UserModel.setPassword(udoc._id, resetpwd);
        // 将用户重定向到创建完成的url
        this.response.redirect = this.url('realname_show');
    }
}

//展示所有用户
class ManageUserHandler extends Handler {
    @query('page', Types.PositiveInt, true)
    @query('group', Types.string, true)
    async get(domainId: string, page = 1, group: string) {

        let filter = { _id: { $gte: 2 } };

	const groups = await UserModel.listGroup(domainId);
        if (group) {
            const groupInfo = groups.find(g => g.name === group);
            if (groupInfo) {
                filter._id = { $in: groupInfo.uids };
            }
        }

        const [dudocs, upcount, ucount] = await paginate(
            UserModel.getMulti(filter).sort({ _id: -1 }),
            page,
            100,
        );
        const udict = await UserModel.getList(domainId, dudocs.map((x) => x._id));
        const udocs = dudocs.map((x) => udict[x._id]);
        this.response.template = 'manage_user.html'; // 返回此页面
        this.response.body = { udocs, upcount, ucount, page, group, groups, };
    }
}

//快速认证
class RealnameQuickHandler extends Handler {
    @query('page', Types.PositiveInt, true)
    async get(domainId: string, page = 1) {
        const [dudocs, upcount, ucount] = await paginate(
            DomainModel.getMultiUserInDomain(domainId, { uid: { $gt: 1 }, "displayName": { $exists: true, $ne: "" } }).sort({ uid: -1 }),
            page,
            100,
        );
        const udict = await UserModel.getList(domainId, dudocs.map((x) => x.uid));
        const udocs = dudocs.map((x) => udict[x.uid]);

        // 根据 realname_flag 进行排序
        udocs.sort((a, b) => {
            const isAEmpty = a.realname_flag == null;
            const isBEmpty = b.realname_flag == null;
            if (isAEmpty && !isBEmpty) return -1;
            if (isBEmpty && !isAEmpty) return 1;
            if (isAEmpty && isBEmpty) return b.uid - a.uid;
            if (a.realname_flag < b.realname_flag) return -1;
            if (a.realname_flag > b.realname_flag) return 1;
            return b.uid - a.uid;
        });

        this.response.template = 'realname_quick.html'; // 返回此页面
        this.response.body = { udocs, upcount, ucount, page, };
    }
}

//添加分组
class DomainRankHandler2 extends Handler {
    @query('page', Types.PositiveInt, true)
    @query('group', Types.string, true)
    async get(domainId: string, page = 1, group: string) {

        let filter = { uid: { $gt: 1 }, rp: { $gt: 0 } };

	const groups = await UserModel.listGroup(domainId);
        if (group) {
            const groupInfo = groups.find(g => g.name === group);
            if (groupInfo) {
                filter.uid = { $in: groupInfo.uids };
            }
        }

        const [dudocs, upcount, ucount] = await this.paginate(
            DomainModel.getMultiUserInDomain(domainId, filter).sort({ rp: -1 }),
            page,
            'ranking',
        );
        const udict = await UserModel.getList(domainId, dudocs.map((dudoc) => dudoc.uid));
        const udocs = dudocs.map((i) => udict[i.uid]);

        this.response.template = 'ranking.html';
        this.response.body = {
            udocs, upcount, ucount, page, group, groups,
        };
    }
}

// 配置项及路由
export async function apply(ctx: Context) {
    ctx.inject(['setting'], (c) => {
        c.setting.AccountSetting(
            SettingModel.Setting('setting_info', 'realname_flag', 0, 'number', '身份标记', '0是未添加身份，1是学生，2是老师', 2),
            SettingModel.Setting('setting_info', 'realname_name', '', 'text', '姓名', null, 2)
        );        
    });
    ctx.Route('realname_show', '/realname/show', RealnameShowHandler);
    ctx.Route('realname_import', '/realname/import', RealnameImportHandler, PRIV.PRIV_SET_PERM);
    ctx.Route('realname_set', '/realname/set', RealnameSetHandler, PRIV.PRIV_SET_PERM);
    ctx.Route('realname_resetpwd', '/realname/resetpwd', ResetPwdHandler, PRIV.PRIV_SET_PERM);
    ctx.Route('realname_quick', '/realname/quick', RealnameQuickHandler, PRIV.PRIV_SET_PERM);
    ctx.Route('用户列表', '/manage/user', ManageUserHandler, PRIV.PRIV_EDIT_SYSTEM);
    ctx.Route('ranking2', '/ranking2', DomainRankHandler2, PERM.PERM_VIEW_RANKING);
    ctx.injectUI('ControlPanel', '用户列表');
    ctx.injectUI('UserDropdown', 'realname_show', { icon: 'feeling-lucky',displayName: '实名认证' });

}
